package com.wangyg.breadstore.controller;

import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.shared.Application;
import com.wangyg.breadstore.dao.BreadRepository;
import com.wangyg.breadstore.model.Bread;
import com.wangyg.breadstore.outer.ICallFlourFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;
import java.util.List;

/**
 * Created by wangyg6 on 2019/5/14.
 * 用于制作面包，其中需要从面粉厂获取原料。所以涉及一个面粉厂的工程，以及通过eureka获取注册的服务
 */
@RestController
@Slf4j
public class BreadController {
	@Autowired
	BreadRepository breadRepository;

	@Autowired
	EurekaClient eurekaClient;

	@Autowired
	LoadBalancerClient loadBalancerClient;

	@Autowired
	@Qualifier("restTemplate")
	RestTemplate restTemplate;
	@Autowired
	@Qualifier("loadBalanceRestTemplate")
	RestTemplate loadbalanceRestTemplate;
	@Autowired
	ICallFlourFactory callFlourFactory;

	//	@Autowired
	//	org.springframework.cloud.client.discovery.DiscoveryClient discoveryClient;

	@PostMapping("/bread")

	public Bread make(@RequestBody Bread param) {
		int count = 0;
		//调用面粉厂获取面粉数量，等同于可做面包个数
	/*	int count2 = getCount2();
		int count1 = getCount1();
		int count3 = getCount3();
		count += count1 + count2 + count3;*/
		count += callFlourFactory.getFlourNum(7);

		//制作面包
		Bread bread1 = Bread.builder().breadId(param.getBreadId()).isWrappered(param.getIsWrappered())
				.createDate(param.getCreateDate()).name(param.getName()).weight(param.getWeight()).quantity(count)
				.build();
		//将面包上架，即入库。
		Bread bread = breadRepository.saveAndFlush(bread1);
		return bread;
	}

	public Integer getCount3() {
		return restTemplate.getForObject(eurekaClient.getNextServerFromEureka("flourfactory", false).getHomePageUrl()
				+ "flour_factory/flourFactory?factId={1}", Integer.class, 7);
	}

	public Integer getCount1() {
		return loadbalanceRestTemplate
				.getForObject("http://flourfactory/flour_factory/flourFactory?factId={1}", Integer.class, 7);
	}

	public int getCount2() {
		ServiceInstance serviceInstance = loadBalancerClient.choose("flourfactory");
		String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort()
				+ "/flour_factory/flourFactory?factId={1}";
		log.info("通过loadbalanceclient获取url:" + url);
		return restTemplate.getForObject(url, Integer.class, 7);
	}

	private Integer getForEntity(String url, RestTemplate template) {

		ResponseEntity<Integer> forEntity = template.getForEntity(url, Integer.class, 7);
		return forEntity.getBody();
	}

	private Integer getForObject(String url, RestTemplate template) {

		return template.getForObject(url, Integer.class, 7);

	}

	private Integer getWithHeader(String url, RestTemplate template) {
		HttpHeaders headers = new HttpHeaders();
		headers.put("Content-Type", Arrays.asList("application/json;charset=UTF-8"));
		HttpEntity<Object> entity = new HttpEntity<Object>(null, headers);
		ResponseEntity<Integer> result = template
				.exchange(url + "flourFactory?factId={1}", HttpMethod.GET, entity, Integer.class, 7);
		return result.getBody();
	}

	/**
	 * 获取实例地址
	 * @return
	 */
	private String getUrl() {
		InstanceInfo instanceInfo = eurekaClient.getNextServerFromEureka("flourfactory", false);
		return instanceInfo.getHomePageUrl();
	}

	@GetMapping("/hh")
	public String hh() {
		InstanceInfo.InstanceStatus instanceRemoteStatus = eurekaClient.getInstanceRemoteStatus();
		List<Application> registeredApplications = eurekaClient.getApplications().getRegisteredApplications();
		for (Application application : registeredApplications) {
			System.out.println(application.getName());
			for (InstanceInfo instanceInfo : application.getInstances()) {
				System.out.println(instanceInfo);

			}
		}
		return "123";
	}

	@GetMapping("/dc")
	public Object getDiscoveryClient() {
		return null;
	}

	/**
	 * 这是一个hystrix command配置样例
	 * Hystrix隔离策略相关的参数 execution.isolation.strategy= THREAD|SEMAPHORE
	 * @return
	 */
	@GetMapping("/test/hystrix")
	public String testCircuitBreaker() {
		return "This is a normal request result";
	}
}